﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace RuleCode.Common
{
    /// <summary>
    /// 枚举 SortingType排序方向
    /// </summary>
    public enum SortingType
    {
        [Caption("降序")]
        DESC = 0,

        [Caption("升序")]
        ASC
    }

    /// <summary>
    /// 枚举 RangeGroupRelation 表示 每个组的原子QueryRange之间的关系是 AND 还是 OR 
    /// </summary>
    public enum RangeGroupRelation
    {
        [Caption (" AND ")]
        AND,

        [Caption (" OR ")]
        OR

       
    }

    /// <summary>
    /// 枚举 RangeAction 过滤操作
    /// </summary>
    public enum RangeAction
    {
        [Caption("=", RangeDataType.AllTypes)]
        EQUAL = 0,

        [Caption("!=", RangeDataType.AllTypes)]
        NOTEQUAL,

        [Caption(">", RangeDataType.AllTypes)]
        LARGER,

        [Caption(">=", RangeDataType.AllTypes)]
        LARGEREQUAL,


        [Caption("<", RangeDataType.AllTypes)]
        LITTLER,

        [Caption("<=", RangeDataType.AllTypes)]
        LITTLEREQUAL,

        [Caption("LIKE", RangeDataType.TStringTypes)]
        LIKE,

        [Caption("NOT LIKE", RangeDataType.TStringTypes)]
        NOTLIKE
    }

    public  struct RangeActionStruct
    {
        public static Dictionary<string, string> RangeActionList
        {
            get 
            {                
                Dictionary<string, string> rangeActionList = new Dictionary<string, string>();
                rangeActionList.Add("LIKE", "LIKE");
                rangeActionList.Add("NOT LIKE", "NOTLIKE");
                rangeActionList.Add("=", "EQUAL");
                rangeActionList.Add("!=", "NOTEQUAL");
                rangeActionList.Add(">", "LARGER");
                rangeActionList.Add(">=", "LARGEREQUAL");
                rangeActionList.Add("<", "LITTLER");
                rangeActionList.Add("<=", "LITTLEREQUAL");

                return rangeActionList;

            }
        }

        public static List<string> NumericActionList
        {
            get 
            {
                List<string> numericActionList = new List<string>();
                numericActionList.AddRange(new string[]{
                    ">=",
                                           "<=",
                                           "=",
                                           "!=",
                                           ">",
                                           "<"
                                           
                                           });
                return numericActionList;
            }
        }

        public static List<string> StringActionList
        {
            get
            {
                List<string> stringActionList = new List<string>();
                stringActionList.AddRange(new string[]{
                                            "=",
                                            "!=",
                                            "LIKE",
                                            "NOT LIKE"
                                            });
                return stringActionList;
            }
        }
    }

    /// <summary>
    /// Select 语句中相关
    /// </summary>
    public struct SetFunction
    {
        public static List<string> NumericFunction
        {
            get 
            {
                List<string> numericFuction = new List<string>();
                numericFuction.AddRange(new string []{
                                        "SELF",
                                        "AVG",
                                        "MIN",
                                        "MAX",
                                        "SUM",
                                        "COUNT",
                                        "MIN_DIS",
                                        "MAX_DIS",
                                        "AVG_DIS",
                                        "SUM_DIS",
                                        "COUNT_DIS"
                                        });
                return numericFuction;
            }
        }

        public static List<string> AllFunction
        {
            get 
            {
                List<string> allFunction = new List<string>();
                allFunction.AddRange(new string[]{
                                    "SELF",
                                    "AVG",
                                    "MIN",
                                    "MAX",
                                    "COUNT",
                                    "SUM",                                   
                                    "MIN_DIS",
                                    "MAX_DIS",
                                    "AVG_DIS",
                                    "SUM_DIS",
                                    "COUNT_DIS"
                                    });
                return allFunction;
            }
        }

        public static List<string> NonNumericFunction
        {
            get
            {
                List<string> nonNumericFunction = new List<string>();
                nonNumericFunction.AddRange(new string []{
                                            "SELF",
                                            "MIN",
                                            "MAX", 
                                            "COUNT",
                                            "MIN_DIS",
                                            "MAX_DIS",                                            
                                            "COUNT_DIS"
                                            });
                return nonNumericFunction;
            }
        }

        public static List<string> CommonFunction
        {
            get 
            {
                List<string> commonFunction = new List<string>();
                commonFunction.AddRange(new string []{
                                        "SELF",
                                        "COUNT",                                        
                                        "COUNT_DIS"
                                        });
                return commonFunction;
            }
        }

        public static List<string> DistinctFunction
        {
            get
            {
                List<string> distinctFunction = new List<string>();
                distinctFunction.AddRange(new string[]{
                                            "MIN_DIS",
                                            "MAX_DIS",
                                            "AVG_DIS",
                                            "COUNT_DIS",
                                            "SUM_DIS"
                                            });
                return distinctFunction;
            }
        }

        public static string GetFieldSelectString(string setFunction, string fieldName)
        {
            if (AllFunction.Contains(setFunction))
            {
                string selectString = " ";
                string distinct = "";
                string setFunctionArg = " ";
                string[] arg = setFunction.Trim().Split("_".ToCharArray());
                if (arg.Length > 1)
                {
                    setFunctionArg = arg[0];
                    if (arg[1] != "")
                    {
                        distinct = " DISTINCT ";
                    }
                }
                else
                {
                    setFunctionArg = setFunction;
                }
                switch (setFunctionArg.ToUpper())
                {
                    case "AVG":
                        {
                            selectString += "AVG("+distinct  + fieldName + ") as " + fieldName;
                            break;
                        }
                    case "MIN":
                        {
                            selectString += "MIN(" + distinct + fieldName + ") as " + fieldName;
                            break;
                        }
                    case "MAX":
                        {
                            selectString += "MAX(" + distinct + fieldName + ") as " + fieldName;
                            break;
                        }
                    case "SUM":
                        {
                            selectString += "SUM(" + distinct + fieldName + ") as " + fieldName;
                            break;
                        }
                    case "COUNT":
                        {
                            selectString += "COUNT(" + distinct + fieldName + ") as " + fieldName;
                            break;
                        }                   
                    case "SELF":
                        {
                            selectString += fieldName;
                            break;
                        }
                }
                return selectString + " ";
            }
            return null;
        }
       
    }

    public enum RangeDataType
    {
        AllTypes=0,
        TStringTypes,
        NumeralTypes        
    }

    public class CaptionAttribute : Attribute
    {
        private static CaptionAttribute instance;
        private string value;
        private RangeDataType rangeDataType;

        public static CaptionAttribute Instance
        {
            get 
            {
                if (instance == null)
                    instance = new CaptionAttribute();
                return instance;
            }
        }

        public CaptionAttribute()
        {
        }
        public CaptionAttribute(string val)
        {
            this.value = val;
        }

        public CaptionAttribute(string val,RangeDataType dataType)
        { 
            this.value = val;
            this.rangeDataType = dataType;
        }

        public string Value
        {
            get { return this.value;  }
            set { this.value = value; }
        }

        public RangeDataType RangeDataType
        {
            get { return  this.rangeDataType; }
            set { this.rangeDataType = value; }
        }

        public  List<System.Type> NumeralTypes
        {
            get
            {
                return  new List<System.Type>() 
                { typeof(TInt), typeof(TFloat), typeof(TDouble), typeof(TDate), typeof(TTime), typeof (TInt64 ) };
                
            }
        }

        public List<System.Type> EnumTypes
        {
            get
            {
                return new List<System.Type>() { typeof (TEnum )};
            }
        }

        public  List<System.Type> TStringTypes
        {
            get
            {
                return  new List<System.Type>() { typeof(TString) };
            }
        }

        public List<System.Type> AllTypes
        {
            get
            {
                List<System.Type> AllTypes = new List<System.Type> ();
                AllTypes .AddRange (this.TStringTypes );
                AllTypes.AddRange(this.NumeralTypes);
                return AllTypes;
            }
        }
    }

}
